/**
 * 抽象工厂模式：根据具体传入的对象来调用子类实现的工厂方法
 * [https://stackoverflow.com/questions/13029261/design-patterns-factory-vs-factory-method-vs-abstract-factory/13030163#13030163]
 */
package main

interface  Plant

class OrangePlant : Plant

class ApplePlant : Plant

abstract class PlantFactory {
    abstract fun makePlant() : Plant

    /**
     * `companion` 修饰为伴生对象,伴生对象在类中只能存在一个，类似于 Java 中的静态方法 Java 中使用类访问静态成员，静态方法。
     */
    companion object {
        inline fun <reified T : Plant> createFactory(): PlantFactory = when (T::class) {
            OrangePlant::class -> OrangeFactory()
            ApplePlant::class  -> AppleFactory()
            else               -> throw IllegalArgumentException()
        }
    }
}


class  AppleFactory : PlantFactory() {
    override fun makePlant(): Plant {
        return ApplePlant()
    }
}

class OrangeFactory : PlantFactory() {
    override fun makePlant(): Plant {
        return OrangePlant()
    }
}

fun main() {
    val plantFactory = PlantFactory.createFactory<OrangePlant>()
    val plant = plantFactory.makePlant()
    println("Created plant: $plant")
}

